//Copyright (C) 2013 Julio Espindola
//
//This file is part of VSize Checkers.
//
//VSize Checkers is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//VSize Checkers is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with VSize Checkers.  If not, see <http://www.gnu.org/licenses/>.

package checkers;

import java.util.ArrayList;
import java.util.Collections;

class MJumps extends Move
{
    ArrayList<Jump> jumps;
    
    MJumps(int start)
    {
        super(start, 0);
        jumps = new ArrayList<Jump>();
    }
    
    MJumps(int newDest, MJumps m)
    {
        super(m.start, newDest);
        jumps = new ArrayList<Jump>(m.jumps.size());
        jumps.addAll(m.jumps);
    }
    
    MJumps(int newDest, MJumps m, boolean crowning)
    {
        super(m.start, newDest, crowning);
        jumps = new ArrayList<Jump>(m.jumps.size());
        jumps.addAll(m.jumps);
    }
    
    void addJump(Jump j)
    {
        jumps.add(j);
    }
    
    void removeJump()
    {
        jumps.remove(jumps.size()-1);
    }
    
    Jump popJump()
    {
        Jump j = jumps.get(jumps.size()-1);
        jumps.remove(jumps.size()-1);
        return j;
    }
    
    Jump getLast()
    {
        return jumps.get(jumps.size()-1);
    }
    
    void make(Board b)
    {
        super.make(b);
       
        for(int i=0; i<jumps.size(); ++i)
        {
            int square = jumps.get(i).cap;
            byte piece = (byte) (jumps.get(i).capPiece&Piece.GET);
           
            b.setPiece(square, Piece.EMPTY);
            b.hash ^= Board.zobrist[(square-1)*4 + (piece>>2)];
           
            if((b.squares[0]&Board.TURN) == 0)
                b.blackMaterial -= (piece&Piece.QUEEN)==0 ? 1 : 3;
            else
                b.whiteMaterial -= (piece&Piece.QUEEN)==0 ? 1 : 3;
        }
    }
   
    void undo(Board b)
    {
        super.undo(b);
       
        for(int i=0; i<jumps.size(); ++i)
        {
            int square = jumps.get(i).cap;
            byte piece = (byte) (jumps.get(i).capPiece&Piece.GET);
           
            b.setPiece(square, piece);
            b.hash ^= Board.zobrist[(square-1)*4 + (piece>>2)];
           
            if((b.squares[0]&Board.TURN) == 0)
                b.whiteMaterial += (piece&Piece.QUEEN)==0 ? 1 : 3;
            else
                b.blackMaterial += (piece&Piece.QUEEN)==0 ? 1 : 3;
        }
    }
    
    boolean alreadyJumped(int square)
    {
        for(Jump j : jumps)
            if(j.cap == square)
                return true;
        return false;
    }
    
    int getDepth()
    {
        return jumps.size();
    }
    
    public int[] getSquares()
    {
        int[] squares = new int[jumps.size()*2];
        for(int i=0; i<squares.length; ++i)
        {
            Jump j = jumps.get(i/2);
            squares[i] = j.start;
            squares[++i] = j.dest;
        }
        return squares;
    }
    
    public int[] getCapSquares()
    {
        int[] squares = new int[jumps.size()];
        for(int i=0; i<squares.length; ++i)
            squares[i] = jumps.get(i).cap;
        return squares;
    }
    
    public int getSize()
    {
        return jumps.size();
    }
    
//    public String detailedInfo()
//    {
//        String s = "===========\nJump: " + start + "x" + dest +"\n";
//        
//        for(int i=0; i<jumps.size(); ++i)
//            s += jumps.get(i) + "\n";
//        
//        return s.substring(0, s.length()-1);
//    }
    
    @Override
    public String toString()
    {
        String s = "===========\nJump: " + start + "x" + dest +"\n";
        
        for(int i=0; i<jumps.size(); ++i)
            s += jumps.get(i) + "\n";
        
        return s.substring(0, s.length()-1);
    }
    
    public boolean equals(Object obj)
    {
        MJumps other = (MJumps) obj;
        if(!super.equals(obj) || jumps.size() != other.jumps.size())
            return false;
        
        for(int i=0; i<jumps.size(); ++i)
            if(!jumps.get(i).equals(other.jumps.get(i)))
                return false;
        
        return true;
    }
}
